<script setup lang="ts">
/**
 * @author lwlianghehe@gmail.com
 * @date 2025/08/04
 */
import { ref, computed } from "vue";
import {
  ElDialog,
  ElButton,
  ElInput,
  ElForm,
  ElFormItem,
  ElSelect,
  ElOption,
} from "element-plus";
import { CodeBlockData } from "./types";

const props = withDefaults(
  defineProps<{
    modelValue?: boolean;
    title?: string;
    width?: string | number;
    height?: string | number;
    initialData?: CodeBlockData;
    showLanguageSelect?: boolean;
  }>(),
  {
    modelValue: false,
    title: "代码块",
    width: "600px",
    height: "600px",
    initialData: () => ({ code: "", language: "javascript" }),
    showLanguageSelect: true,
  }
);

const emit = defineEmits<{
  (e: "update:modelValue", value: boolean): void;
  (e: "confirm", data: CodeBlockData): void;
  (e: "cancel"): void;
}>();

const formData = ref<CodeBlockData>({
  code: props.initialData.code,
  language: props.initialData.language,
});

const dialogVisible = computed({
  get: () => props.modelValue,
  set: (val: boolean) => {
    emit("update:modelValue", val);
  },
});

const formRef = ref();

const rules = {
  code: [{ required: true, message: "请输入代码内容", trigger: "blur" }],
};

// 支持的编程语言列表
const languageOptions = [
  { value: "javascript", label: "JavaScript" },
  { value: "typescript", label: "TypeScript" },
  { value: "html", label: "HTML" },
  { value: "css", label: "CSS" },
  { value: "python", label: "Python" },
  { value: "java", label: "Java" },
  { value: "cpp", label: "C++" },
  { value: "csharp", label: "C#" },
  { value: "php", label: "PHP" },
  { value: "ruby", label: "Ruby" },
  { value: "go", label: "Go" },
  { value: "rust", label: "Rust" },
  { value: "sql", label: "SQL" },
  { value: "json", label: "JSON" },
  { value: "xml", label: "XML" },
  { value: "yaml", label: "YAML" },
  { value: "markdown", label: "Markdown" },
  { value: "bash", label: "Bash" },
  { value: "powershell", label: "PowerShell" },
  { value: "plaintext", label: "Plain Text" },
];

const handleConfirm = async () => {
  try {
    await formRef.value.validate();
    emit("confirm", formData.value);
    dialogVisible.value = false;
  } catch (error) {
    // 验证失败，不关闭对话框
  }
};

const handleCancel = () => {
  emit("cancel");
  dialogVisible.value = false;
  // 重置表单数据
  formData.value = {
    code: props.initialData.code,
    language: props.initialData.language,
  };
};

// 监听初始数据变化
const resetFormData = () => {
  formData.value = {
    code: props.initialData.code,
    language: props.initialData.language,
  };
};

// 当对话框打开时重置数据
const handleOpen = () => {
  resetFormData();
};
</script>

<template>
  <el-dialog
    v-model="dialogVisible"
    :title="title"
    :width="width"
    :close-on-click-modal="false"
    :close-on-press-escape="true"
    @open="handleOpen"
  >
    <el-form ref="formRef" :model="formData" :rules="rules" label-width="80px">
      <el-form-item v-if="showLanguageSelect" label="语言" prop="language">
        <el-select
          v-model="formData.language"
          placeholder="选择编程语言"
          style="width: 100%"
        >
          <el-option
            v-for="option in languageOptions"
            :key="option.value"
            :label="option.label"
            :value="option.value"
          />
        </el-select>
      </el-form-item>

      <el-form-item label="代码" prop="code" required>
        <el-input
          v-model="formData.code"
          type="textarea"
          :rows="15"
          :autosize="{ minRows: 15, maxRows: 25 }"
          placeholder="请输入代码内容..."
        />
      </el-form-item>
    </el-form>

    <template #footer>
      <el-button @click="handleCancel">取消</el-button>
      <el-button type="primary" @click="handleConfirm">确定</el-button>
    </template>
  </el-dialog>
</template>

<style scoped>
.el-form-item {
  margin-bottom: 20px;
}

.el-form-item__label::before {
  content: "*";
  color: #f56c6c;
  margin-right: 4px;
}

:deep(.el-textarea__inner) {
  font-family: "Courier New", "Monaco", "Menlo", "Ubuntu Mono", monospace;
  font-size: 14px;
  line-height: 1.5;
  tab-size: 2;
}

:deep(.el-textarea__inner:focus) {
  border-color: var(--el-color-primary);
}
</style>
